/* 点亮LED以示庆祝 :-) */
/* LED0在PA8，LED1在PD2，低电平点亮 */
/* 编译后共104 Bytes */

    .equ STACK_TOP, 0x20000800//SRAM: 0x2000 0000~0x2000 AFFF
    .equ RCC_APB2ENR, 0x40021018
    .equ GPIOA_CRH, 0x40010804
    .equ GPIOD_CRL, 0x40011400
    .equ GPIOA_BSRR, 0x40010810
    .equ GPIOD_BSRR, 0x40011410
    .text
    .global _start
    .global delay_ms
    //.code 16
    .thumb//等价于.code 16
    .syntax unified//统一汇编语言语法
    .arch armv7-m

//interruption vector table
_start:
    .word STACK_TOP, Reset_Handler
    .type Reset_Handler, %function//Thumb模式要求PC的LSB为1

Reset_Handler:
    /* 启动GPIO port：
    1. 开启时钟
    2. 配置为推挽输出 */
    ldr r0, =RCC_APB2ENR
    mov r1, #0x24
    strb r1, [r0]//不规范，只为开启GPIOA和GPIOD的时钟
    ldr r0, =GPIOA_CRH
    mov r1, #0x1
    str r1, [r0]//PA8为推挽输出
    ldr r0, =GPIOD_CRL
    mov r1, #0x0100
    str r1, [r0]//PD2为推挽输出

//使用 BSRR 寄存器来置位、复位，经验证OK
    ldr r11, =400000
    ldr r2, =GPIOA_BSRR
    ldr r3, =GPIOD_BSRR
    mov r0, #1
    lsl r0, #24
    mov r1, #1
    lsl r1, #2

loop:
    lsr r0, #16//24-16=8
    str r0, [r2]//PA8 = 1
    lsl r1, #16//2+16=18
    str r1, [r3]//PD2 = 0
    bl delay_ms

    lsl r0, #16//8+16=24
    str r0, [r2]//PA8=0
    lsr r1, #16//18-16=2
    str r1, [r3]//PD2=1
    bl delay_ms
    b loop

/*
//使用别名区来置位、复位，经验证OK
    ldr r0, =#0x42000000//别名区基地址
    ldr r2, =#0x1080D//GPIOA_ODR第二个字节
    ldr r3, =#0x1140C//GPIOD_ODR第一个字节
    lsl r2, #3
    add r2, #0
    lsl r2, #2
    add r2, r0, r2//得到GPIOA_ODR bit:8的别名
    lsl r3, #3
    add r3, #2
    lsl r3, #2
    add r3, r0, r3//得到GPIOD_ODR bit:2的别名
    mov r0, #0//0: LED on
    mov r1, #1//1: LED off

loop:
    bl wait300ms
    str r0, [r2]
    str r1, [r3]
    bl wait300ms
    str r1, [r2]
    str r0, [r3]
    B loop
*/
    .end
